#pragma once
#include"Log.hpp"
#include<functional>
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/socket.h>
#include <netinet/in.h>
#include<string.h>
#include"mutex.hpp"
#include"InetAddr.hpp"
using namespace LogModule;
using namespace MutexModule;

using fun_c=std::function<void(int&,const std::string&,InetAddr&)>;
int defaultsockid=-1;
class UdpServe
{
public:
    UdpServe(uint16_t port,fun_c func)
    :_sockid(defaultsockid)
    ,_port(port)
    ,_func(func)
    ,_isrunning(0)
    {}
    void Init()
    {
        _sockid=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockid<0)
        {
            LOG(LogLevel::ERROR)<<"socket失败"<<"\n";
        }
        struct sockaddr_in local;
        bzero(&local,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(_port);
        local.sin_addr.s_addr=INADDR_ANY;

        //InetAddr addr("0",_port);
        int n=bind(_sockid,(struct sockaddr*)&local,sizeof(local));
        (void)n;
       
        LOG(LogLevel::DEBUG)<<"bind success";
    }
    void Start()
    {
        _isrunning=true;
        LOG(LogLevel::INFO)<<"服务器开始运行";
        while(_isrunning)
        {
            char buffer[1024];
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);
           
            size_t n=recvfrom(_sockid,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            if(n>0)
            {
                std::cout<<peer.sin_addr.s_addr<<std::endl;
                InetAddr client(peer);
                buffer[n]=0;
                LOG(LogLevel::INFO)<<"get info from "<<client.Ip()<<" "<<client.Port()<<":->"<<buffer;
                _func(_sockid,buffer,client);
                //sendto(_sockid,resault.c_str(),resault.size(),0,(struct sockaddr*)&peer,len);
            }
        }
    }
    ~UdpServe(){};
private:
    //std::string _ip;
    int _sockid;
    uint16_t _port;
    fun_c _func;
    bool _isrunning;
    
};
